import requests
import copy
import time
import Utils
import re
import json
from string import Template
import hashlib


head = {
    'Connection': 'keep-alive',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
    'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.9'
}

public_property = {
    'personid' : None,
    'chapterId' : None,
    'courseId' : None,
    'clazzid' : None,
    'enc' :None,
    'userid':None,
}

session = requests.session()

def getTime():
    theTime = int(time.time()*1000)

    return str(theTime)



def login(username, password):
    # session  = requests.session()


    the_head = copy.deepcopy(head)
    the_head['Host'] = 'passport2.chaoxing.com'
    the_head['Origin'] = 'http://passport2.chaoxing.com'
    the_head['Referer'] = 'http://passport2.chaoxing.com/login'

    url_code = 'http://passport2.chaoxing.com/num/code?'+getTime()
    url_login = 'http://passport2.chaoxing.com/login'

    password = Utils.encode(password)

    data = {
        'refer_0x001': 'http%3A%2F%2Fi.mooc.chaoxing.com',
        'pid': -1,
        'pidName': '',
        'fid': -1,
        'fidName': '',
        'allowJoin': 0,
        'isCheckNumCode': 1,
        'f': 0,
        'productid': '',
        't': 'true',
        'uname': username,
        'password': password,
        'numcode': '',
        'verCode': ''
    }

    r = session.get(url_code, headers = the_head)

    file = open('image/code.jpg','wb+')
    file.write(r.content)
    file.close()
    data['numcode'] = input("请输入验证码")

    r = session.post(url_login, headers = the_head, data = data, allow_redirects=False)

    url_index = r.headers['location']
    the_head['Host'] = 'i.mooc.chaoxing.com'
    the_head['Referer'] = 'http://passport2.chaoxing.com/'
    the_head['Upgrade-Insecure-Requests'] = '1'

    r = session.get(url_index)

    if(r.status_code == 200):
        text = r.text

        res = re.search(r'<iframe src="http://mooc1-1.chaoxing.com/visit/interaction\?s=(.*?) name="frame_content"',text)
        userid = re.search(r"\s*url:'/space/incode_site\.shtml\?incode='\+incode\+'&uid=(.*?)&",text) #获取userid

        public_property['userid'] = userid.group(1)

        if(res is None):
            print("未找到课程端")
            return None

        else:
            return res.group(1)

    else:
         return False

#该函数的功能是获取账号的所有课程（不包括已结课的）
#s是login()的返回值
def getCourses(s):
    courses = []
    
    the_head = copy.deepcopy(head)
    
    the_head['Host'] = 'mooc1-1.chaoxing.com'
    the_head['Referer'] = 'http://i.mooc.chaoxing.com/'
    the_head['Upgrade-Insecure-Requests'] = '1'

    #第一个为课程地址 第二个为课程名 第三个为授课老师
    getCoursesRule = r'<a class="courseName"  href=\'(.*?)\' target="_blank" title="(.*?)">.*?</a>\s*<i> </i>\s*</h3>\s*<p title="(.*?)">.*?</p>'

    url = "http://mooc1-1.chaoxing.com/visit/interaction"

    if(s is not None):
        url = "http://mooc1-1.chaoxing.com/visit/interaction?s="+s

    r = session.get(url,headers = the_head)

    res_list = re.findall(getCoursesRule, r.text)

    for res in res_list:
        course = {}
        course['url'] = res[0]
        course['course_name'] = res[1]
        course['teacher_name'] = res[2]

        courses.append(course)


    return courses

#获取课程的html
def getCourseHtml(url):
    the_head = copy.deepcopy(head)
    r = session.get("https://mooc1-1.chaoxing.com"+url,headers = head, allow_redirects=False)
    url = r.headers['location']

    r = session.get(url,headers = head)

    return r.text

#通过url的传参赋值给 public_property对应的属性
#https://mooc1-1.chaoxing.com/visit/stucoursemiddle?courseid=216953158&clazzid=37739363&vc=1&cpi=102816494
def initProperty(url):
    res = re.findall(r'courseid=(.*?)&clazzid=(.*?)&vc=(.*?)&cpi=(.*)$', url)

    public_property['courseid'] = res[0][0]
    public_property['clazzid'] = res[0][1]
    public_property['cpi'] = res[0][3]
    public_property['personId'] = res[0][3]

#获取课程所有知识点
#html表示课程地址的html
def getCourseChapter(html):

    course_chapter_list = []
    get_course_chapter_url_rule = r'href=\'(/mycourse/studentstudy\?chapterId=.*?&courseId=.*?&clazzid=.*?&enc=.*?)\''
    get_course_chapter_name_rule = r'<span class="articlename" title="(.*?)">'
    get_course_chapter_number_rule = r'<span class="chapterNumber">(.*?)</span>'

    course_chapter_url_list = re.findall(get_course_chapter_url_rule, html)
    course_chapter_name_list = re.findall(get_course_chapter_name_rule, html)
    course_chapter_number_list = re.findall(get_course_chapter_number_rule, html)
    course_length = len(course_chapter_name_list)

    for i in range(course_length):
        chapter = {}

        chapter['url'] = "https://mooc1-1.chaoxing.com" + course_chapter_url_list[i]
        chapter['name'] = course_chapter_name_list[i]
        chapter['number'] = course_chapter_number_list[i]

        course_chapter_list.append(chapter)

    return course_chapter_list

#获取课程讨论的全部话题
''''
第一个参数html:课程的html

返回值：讨论对象的数组
''''
def getDiscussTopics(html):
    the_head = copy.deepcopy(head)
    the_head['Host'] = 'mooc1-1.chaoxing.com'

    get_discuss_url_rule = r'<li><a mode="fuseMode"  href="(.*?)" title="讨论">讨论</a></li>' #讨论的地址
    get_discuss_topic_rule = r'<a href="(.*?)"\s*.*?><span.*?>(.*?\s*){2}</span>' #话题

    discuss_topic_list = []

    res = re.search(get_discuss_url_rule, html)

    url = ""

    if(res is None):
        return None

    else:
        url = res.group(1)

    r = session.get(url,headers=the_head)

    res_list = re.findall(get_discuss_topic_rule, r.text)

    for res in res_list:
        discuss_topic = {}

        discuss_topic['url'] = res[0]
        discuss_topic['topic'] = res[1]

        discuss_topic_list.append(discuss_topic)

    return discuss_topic_list

#获取知识点讨论话题
def getChapterTopic(chapter_url,length):
    print(chapter_url)

#完成章节课程的任务
#第一个参数为课程章节的地址
def completeChapter(chapter_url):
    #url = "https://mooc1-1.chaoxing.com/mycourse/studentstudyAjax"
    res = re.search(r'chapterId=(.*?)&courseId=(.*?)&clazzid=(.*?)&', chapter_url)
    
    the_head = copy.deepcopy(head)
    the_head['Referer'] = chapter_url
    the_head['Host'] = "mooc1-1.chaoxing.com"

    chapterId = res.group(1)
    courseId = res.group(2)
    clazzid = res.group(3)
    count = getChapterCount(chapter_url)

    #遍历章节中的所有知识卡片
    for num in range(count):
        url = "https://mooc1-1.chaoxing.com/knowledge/cards?clazzid="+clazzid+"&courseid="+courseId+"&knowledgeid="+chapterId+"&num="+str(num)+"&ut=s&cpi=102816494&v=20160407-1"

        r = session.get(url, headers = the_head)

        html = r.text

        #获取知识卡片的JSON数据
        res = re.search(r'\s*mArg = ({.*?});',html)

        try:
            mArg = res.group(1)
        except:
            continue
        else:

            mArg = json.loads(mArg)

            objectid = None
            jobid = None
            duration = None
            dtoken = None
            userid = public_property['userid']

            #自动完成该知识卡片的视频
            #查看mArg中是否有相应的数据,如果没有，那么可以判断这个知识卡片没有视频
            if('attachments' in mArg.keys() and len(mArg['attachments']) > 0):
                attachments = mArg['attachments']

                for attachment in attachments:
                    if('property' in attachment.keys()):
                        the_head['Referer'] = 'https://mooc1-1.chaoxing.com/ananas/modules/video/index.html?v=2021-0507-1719'
                        the_head['Host'] = 'mooc1-1.chaoxing.com'
                        if('objectid' in attachment['property'].keys()):
                            objectid = attachment['property']['objectid']
                            url = 'https://mooc1-1.chaoxing.com/ananas/status/'+objectid+'?k=11087&flag=normal&_dc='+getTime()

                        elif('objectId' in attachment.keys()):
                            objectid = attachment['objectId']

                            url = 'https://mooc1-1.chaoxing.com/ananas/status/'+objectid+'?k=11087&flag=normal&_dc='+getTime()

                        if('jobid' in attachment['property'].keys()):
                            jobid = attachment['property']['jobid']

                        elif('_jobid' in attachment['property'].keys()):
                            jobid = attachment['property']['_jobid']

                        r = session.get(url, headers = the_head)

                        video_info = r.text
                        
                        try:
                            video_info = json.loads(video_info)

                        except:
                            print("未找到任何视频相关的数据")
                            continue

                        else:

                            #如果存在视频播放长度，那么就自动刷视频
                            if('duration' in video_info.keys()):
                                duration = video_info['duration']

                            if('dtoken' in video_info.keys()):
                                dtoken = video_info['dtoken']

                            #如果下面属性为None 那么说明没有找到视频或未找到必要的信息 那么将会重新遍历
                            if(duration is None or dtoken is None or objectid is None or jobid is None or userid is None):
                                continue

                            md5 = hashlib.md5()
                            enc = Template("[$clazzid][$userid][$jobid][$objectid][$currentTimeSec][d_yHJ!$$pdA~5][$duration][0_$duration2]")
                            enc = enc.substitute(clazzid = clazzid, userid = userid, jobid = jobid, objectid = objectid, currentTimeSec = duration * 1000, duration = duration * 1000, duration2 = duration)
                            md5.update(bytes(enc.encode()))
                            enc = md5.hexdigest()

                            url = "https://mooc1-1.chaoxing.com/multimedia/log/a/102816494/"+dtoken+"?clazzId="+clazzid+"&playingTime="+str(duration)+"&duration="+str(duration)+"&clipTime="+str(0)+"_"+str(duration)+"&objectId="+objectid+"&otherInfo=nodeId_"+chapterId+"-cpi_"+public_property['cpi']+"&jobid="+jobid+"&userid="+userid+"&isdrag=4&view=pc&enc="+enc+"&rt=0.9&dtype=Video&_t="+getTime()
                            the_head['Referer'] = 'https://mooc1-1.chaoxing.com/ananas/modules/video/index.html?v=2021-0507-1719'
                            the_head['Host'] = 'mooc1-1.chaoxing.com'
                            r = session.get(url, headers = the_head)
                            print(r.text)
                            time.sleep(3)

            



#获取知识点的导航栏的个数
#第一个参数为知识点的地址
#返回值是int类型的数值 表示知识点里有多少个导航栏 或者 None 表示没有找到
def getChapterCount(ref_url):
    url = 'https://mooc1-1.chaoxing.com/mycourse/studentstudyAjax'

    res = re.findall(r'chapterId=(.*?)&courseId=(.*?)&clazzid=(.*?)&enc=(.*?)',ref_url)
    chapterId = res[0][0]
    courseId = res[0][1]
    clazzid = res[0][2]
    cpi = public_property['cpi']

    the_head = copy.deepcopy(head)
    the_head['Host'] = 'mooc1-1.chaoxing.com'
    the_head['Origin'] = 'https://mooc1-1.chaoxing.com'
    the_head['Referer'] = ref_url

    data = {
        'courseId' : courseId,
        'clazzid' : clazzid,
        'chapterId' : chapterId,
        'cpi' : cpi
    }

    r = session.post(url, headers = the_head, data = data)

    res = re.search(r'<input id="cardcount" type="hidden" value="(.*?)">', r.text)

    if(res == None):
        return None

    else:
        return int(res.group(1))

#打印课程章节的数组
def printCourseChapterList(course_chapter_list):
    for i in range(len(course_chapter_list)):
        print("索引========"+str(i))
        print("章节名字: "+course_chapter_list[i]['name'])
        print("课程章节: " + course_chapter_list[i]['number'])

#第一个参数为 课程列表
def printCourseList(course_list):
    for i in range(len(course_list)):
        print("当前索引=========="+ str(i))
        print("课程名字"+ course_list[i]['course_name'])
        print("授课老师"+ course_list[i]['teacher_name'])


#course_url为课程地址
def autoVideo(course_url):
    initProperty(course_url)
    course_html = getCourseHtml(course_url)
    course_chapter_list = getCourseChapter(course_html)

    printCourseChapterList(course_chapter_list)
    index = int(input("请选择你要开始学习的地方:"))
    
    for i in range(index, len(course_chapter_list)):
        print("尝试刷-----"+course_chapter_list[i]['number']+course_chapter_list[i]['name'])
        completeChapter(course_chapter_list[i]['url'])

def main():
    s = login('phoneNumber','password')
    course_list = getCourses(s)
    printCourseList(course_list)
    index = int(input("请选择你要学习的课程"))

    # input("请选择你需要的功能")
    autoVideo(course_list[index]['url'])

main()
